#ifndef __NPY_SIMD_DATA_H_
#define __NPY_SIMD_DATA_H_
#if defined NPY_HAVE_AVX512F
#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
/*
 * Constants used in vector implementation of float64 exp(x)
 */
#define NPY_RINT_CVT_MAGIC 0x1.8p52
#define NPY_INV_LN2_MUL_32 0x1.71547652b82fep+5
#define NPY_TANG_NEG_L1 -0x1.62e42fefp-6
#define NPY_TANG_NEG_L2 -0x1.473de6af278edp-39
#define NPY_TANG_A1 0x1p-1
#define NPY_TANG_A2 0x1.5555555548f7cp-3
#define NPY_TANG_A3 0x1.5555555545d4ep-5
#define NPY_TANG_A4 0x1.11115b7aa905ep-7
#define NPY_TANG_A5 0x1.6c1728d739765p-10

#if !defined NPY_HAVE_AVX512_SKX || !defined NPY_CAN_LINK_SVML
/* Lookup table for 2^(j/32) */
static npy_uint64 EXP_Table_top[32] = {
    0x3FF0000000000000,
    0x3FF059B0D3158540,
    0x3FF0B5586CF98900,
    0x3FF11301D0125B40,
    0x3FF172B83C7D5140,
    0x3FF1D4873168B980,
    0x3FF2387A6E756200,
    0x3FF29E9DF51FDEC0,
    0x3FF306FE0A31B700,
    0x3FF371A7373AA9C0,
    0x3FF3DEA64C123400,
    0x3FF44E0860618900,
    0x3FF4BFDAD5362A00,
    0x3FF5342B569D4F80,
    0x3FF5AB07DD485400,
    0x3FF6247EB03A5580,
    0x3FF6A09E667F3BC0,
    0x3FF71F75E8EC5F40,
    0x3FF7A11473EB0180,
    0x3FF82589994CCE00,
    0x3FF8ACE5422AA0C0,
    0x3FF93737B0CDC5C0,
    0x3FF9C49182A3F080,
    0x3FFA5503B23E2540,
    0x3FFAE89F995AD380,
    0x3FFB7F76F2FB5E40,
    0x3FFC199BDD855280,
    0x3FFCB720DCEF9040,
    0x3FFD5818DCFBA480,
    0x3FFDFC97337B9B40,
    0x3FFEA4AFA2A490C0,
    0x3FFF50765B6E4540,
};

static npy_uint64 EXP_Table_tail[32] = {
    0x0000000000000000,
    0x3D0A1D73E2A475B4,
    0x3CEEC5317256E308,
    0x3CF0A4EBBF1AED93,
    0x3D0D6E6FBE462876,
    0x3D053C02DC0144C8,
    0x3D0C3360FD6D8E0B,
    0x3D009612E8AFAD12,
    0x3CF52DE8D5A46306,
    0x3CE54E28AA05E8A9,
    0x3D011ADA0911F09F,
    0x3D068189B7A04EF8,
    0x3D038EA1CBD7F621,
    0x3CBDF0A83C49D86A,
    0x3D04AC64980A8C8F,
    0x3CD2C7C3E81BF4B7,
    0x3CE921165F626CDD,
    0x3D09EE91B8797785,
    0x3CDB5F54408FDB37,
    0x3CF28ACF88AFAB35,
    0x3CFB5BA7C55A192D,
    0x3D027A280E1F92A0,
    0x3CF01C7C46B071F3,
    0x3CFC8B424491CAF8,
    0x3D06AF439A68BB99,
    0x3CDBAA9EC206AD4F,
    0x3CFC2220CB12A092,
    0x3D048A81E5E8F4A5,
    0x3CDC976816BAD9B8,
    0x3CFEB968CAC39ED3,
    0x3CF9858F73A18F5E,
    0x3C99D3E12DD8A18B,
};
#endif //#if !defined NPY_HAVE_AVX512_SKX || !defined NPY_CAN_LINK_SVML
#endif
#endif

/*
 * Constants used in vector implementation of exp(x)
 */
#define NPY_RINT_CVT_MAGICf 0x1.800000p+23f
#define NPY_CODY_WAITE_LOGE_2_HIGHf -6.93145752e-1f
#define NPY_CODY_WAITE_LOGE_2_LOWf -1.42860677e-6f
#define NPY_COEFF_P0_EXPf 9.999999999980870924916e-01f
#define NPY_COEFF_P1_EXPf 7.257664613233124478488e-01f
#define NPY_COEFF_P2_EXPf 2.473615434895520810817e-01f
#define NPY_COEFF_P3_EXPf 5.114512081637298353406e-02f
#define NPY_COEFF_P4_EXPf 6.757896990527504603057e-03f
#define NPY_COEFF_P5_EXPf 5.082762527590693718096e-04f
#define NPY_COEFF_Q0_EXPf 1.000000000000000000000e+00f
#define NPY_COEFF_Q1_EXPf -2.742335390411667452936e-01f
#define NPY_COEFF_Q2_EXPf 2.159509375685829852307e-02f

/*
 * Constants used in vector implementation of log(x)
 */
#define NPY_COEFF_P0_LOGf 0.000000000000000000000e+00f
#define NPY_COEFF_P1_LOGf 9.999999999999998702752e-01f
#define NPY_COEFF_P2_LOGf 2.112677543073053063722e+00f
#define NPY_COEFF_P3_LOGf 1.480000633576506585156e+00f
#define NPY_COEFF_P4_LOGf 3.808837741388407920751e-01f
#define NPY_COEFF_P5_LOGf 2.589979117907922693523e-02f
#define NPY_COEFF_Q0_LOGf 1.000000000000000000000e+00f
#define NPY_COEFF_Q1_LOGf 2.612677543073109236779e+00f
#define NPY_COEFF_Q2_LOGf 2.453006071784736363091e+00f
#define NPY_COEFF_Q3_LOGf 9.864942958519418960339e-01f
#define NPY_COEFF_Q4_LOGf 1.546476374983906719538e-01f
#define NPY_COEFF_Q5_LOGf 5.875095403124574342950e-03f

/*
 * Lookup table of log(c_k)
 * Reference form: Tang, Ping-Tak Peter. "Table-driven implementation of the
 *     logarithm function in IEEE floating-point arithmetic." ACM Transactions
 *     on Mathematical Software (TOMS) 16.4 (1990): 378-400.
 */
#if defined NPY_HAVE_AVX512F
#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
#if !defined NPY_HAVE_AVX512_SKX || !defined NPY_CAN_LINK_SVML
static npy_uint64 LOG_TABLE_TOP[64] = {
    0x0000000000000000,
    0x3F8FC0A8B1000000,
    0x3F9F829B0E780000,
    0x3FA77458F6340000,
    0x3FAF0A30C0100000,
    0x3FB341D7961C0000,
    0x3FB6F0D28AE60000,
    0x3FBA926D3A4A0000,
    0x3FBE27076E2A0000,
    0x3FC0D77E7CD10000,
    0x3FC29552F8200000,
    0x3FC44D2B6CCB0000,
    0x3FC5FF3070A80000,
    0x3FC7AB8902110000,
    0x3FC9525A9CF40000,
    0x3FCAF3C94E810000,
    0x3FCC8FF7C79B0000,
    0x3FCE27076E2B0000,
    0x3FCFB9186D5E0000,
    0x3FD0A324E2738000,
    0x3FD1675CABAB8000,
    0x3FD22941FBCF8000,
    0x3FD2E8E2BAE10000,
    0x3FD3A64C55698000,
    0x3FD4618BC21C8000,
    0x3FD51AAD872E0000,
    0x3FD5D1BDBF580000,
    0x3FD686C81E9B0000,
    0x3FD739D7F6BC0000,
    0x3FD7EAF83B828000,
    0x3FD89A3386C18000,
    0x3FD947941C210000,
    0x3FD9F323ECBF8000,
    0x3FDA9CEC9A9A0000,
    0x3FDB44F77BCC8000,
    0x3FDBEB4D9DA70000,
    0x3FDC8FF7C79A8000,
    0x3FDD32FE7E010000,
    0x3FDDD46A04C20000,
    0x3FDE744261D68000,
    0x3FDF128F5FAF0000,
    0x3FDFAF588F790000,
    0x3FE02552A5A5C000,
    0x3FE0723E5C1CC000,
    0x3FE0BE72E4254000,
    0x3FE109F39E2D4000,
    0x3FE154C3D2F4C000,
    0x3FE19EE6B467C000,
    0x3FE1E85F5E704000,
    0x3FE23130D7BEC000,
    0x3FE2795E1289C000,
    0x3FE2C0E9ED448000,
    0x3FE307D7334F0000,
    0x3FE34E289D9D0000,
    0x3FE393E0D3564000,
    0x3FE3D9026A714000,
    0x3FE41D8FE8468000,
    0x3FE4618BC21C4000,
    0x3FE4A4F85DB04000,
    0x3FE4E7D811B74000,
    0x3FE52A2D265BC000,
    0x3FE56BF9D5B40000,
    0x3FE5AD404C358000,
    0x3FE5EE02A9240000,
};

static npy_uint64 LOG_TABLE_TAIL[64] = {
    0x0000000000000000,
    0xBD5FE0E183092C59,
    0x3D2980267C7E09E4,
    0xBD62303B9CB0D5E1,
    0x3D662A6617CC9717,
    0xBD4717B6B33E44F8,
    0xBD62968C836CC8C2,
    0x3D6AAC6CA17A4554,
    0x3D6E5CBD3D50FFFC,
    0xBD6C69A65A23A170,
    0xBD35B967F4471DFC,
    0x3D6F4799F4F6543E,
    0xBD6B0B0DE3077D7E,
    0xBD537B720E4A694B,
    0x3D65AD1D904C1D4E,
    0xBD600349CC67F9B2,
    0xBD697794F689F843,
    0xBD3A342C2AF0003C,
    0x3D5F1546AAA3361C,
    0x3D50E35F73F7A018,
    0x3D630701CE63EAB9,
    0xBD3A6976F5EB0963,
    0x3D5D309C2CC91A85,
    0xBD6D0B1C68651946,
    0xBD609EC17A426426,
    0xBD3F4BD8DB0A7CC1,
    0x3D4394A11B1C1EE4,
    0x3D54AEC442BE1015,
    0xBD67FCB18ED9D603,
    0x3D67E1B259D2F3DA,
    0xBD6ED2A52C73BF78,
    0x3D56FABA4CDD147D,
    0x3D584BF2B68D766F,
    0x3D40931A909FEA5E,
    0x3D4EC5197DDB55D3,
    0x3D5B7BF7861D37AC,
    0x3D5A21AC25DB1EF3,
    0xBD542A9E21373414,
    0xBD6DAFA08CECADB1,
    0x3D3E1F8DF68DBCF3,
    0x3D3BB2CD720EC44C,
    0xBD49C24CA098362B,
    0x3D60FEC69C695D7F,
    0x3D6F404E57963891,
    0xBD657D49676844CC,
    0x3D592DFBC7D93617,
    0x3D65E9A98F33A396,
    0x3D52DD98B97BAEF0,
    0x3D1A07BD8B34BE7C,
    0xBD17AFA4392F1BA7,
    0xBD5DCA290F818480,
    0x3D5D1772F5386374,
    0x3D60BE1FB590A1F5,
    0xBD6E2CE9146D271A,
    0xBD65E6563BBD9FC9,
    0x3D66FAA404263D0B,
    0xBD5AA33736867A17,
    0x3D6EC27D0B7B37B3,
    0xBD244FDD840B8591,
    0x3D6BB09CB0985646,
    0x3D46ABB9DF22BC57,
    0xBD58CD7DC73BD194,
    0x3D6F2CFB29AAA5F0,
    0x3D66757006095FD2,
};
#endif //#if !defined NPY_HAVE_AVX512_SKX || !defined NPY_CAN_LINK_SVML

#define NPY_TANG_LOG_A1 0x1.55555555554e6p-4
#define NPY_TANG_LOG_A2 0x1.9999999bac6d4p-7
#define NPY_TANG_LOG_A3 0x1.2492307f1519fp-9
#define NPY_TANG_LOG_A4 0x1.c8034c85dfffp-12

#define NPY_TANG_LOG_LN2HI 0x1.62e42fefa4p-1
#define NPY_TANG_LOG_LN2LO -0x1.8432a1b0e2634p-43
#endif
#endif

#endif
